/**
 * 
 */
package com.base.myproject.client.ui.celleditor;

import java.util.List;

import com.base.myproject.client.busi.BaseStore;
import com.base.myproject.client.jdbc.StoreInfo;
import com.base.myproject.client.tools.CommandSyncContainer;
import com.base.myproject.client.tools.CommandSyncGetModelDatas;
import com.base.myproject.client.tools.CommandSyncReturnObject;
import com.extjs.gxt.ui.client.data.LoadEvent;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.ModelType;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.LoadListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.StoreFilter;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * form方式下面的combobox，支持自动匹配, 注意 在store里面必须有 code和name，这两个字段才是真正使用到的
 * 否则会报找不到值的空指针错误。 没有用到延时加载，在界面打开时候就运行。
 * 
 * @author zgw 2009-9-3 下午04:23:56 javazgw@gmail.com
 */
public class BaseComboBoxForm<D extends ModelData> extends ComboBox<D>
		implements GridCellRenderer {

	String value;
	String displayvalue;
	BaseStore<D> bs;
	final java.util.Map<String, String> ht = new java.util.HashMap<String, String>();

	public BaseComboBoxForm() {

		super();

	}

	public BaseComboBoxForm(String value, String displayvalue, BaseStore<D> bs) {
		this(value, displayvalue, bs, false);

	}

	/**
	 * 
	 * @param value
	 * @param displayvalue
	 * @param bs
	 * @param b
	 *            默认false ，true为渲染
	 */
	public BaseComboBoxForm(final String value, final String displayvalue,
			final BaseStore<D> bs, boolean b) {

		this.value = value;
		this.displayvalue = displayvalue;
		this.setStore(bs);
		this.setDisplayField(displayvalue);
		//setTypeAhead(true);
		setTriggerAction(TriggerAction.ALL);
		setAutoValidate(true);

		// setForceSelection(true);
		if (b) {
			bs.getLoader().addLoadListener(new LoadListener() {
				public void loaderLoad(LoadEvent le) {
					ht.clear();

					for (int i = 0; i < bs.getModels().size(); i++) {
						ht.put(((ModelData) bs.getModels().get(i)).get(value)
								.toString(),
								((ModelData) bs.getModels().get(i)).get(
										displayvalue).toString());

					}
				}
			});
		}
		// else
		// {
		// ht.clear();
		// Debug.printf("--已经读取");
		// for (int i = 0; i < bs.getModels().size(); i++) {
		// ht.put(((ModelData)bs.getModels().get(i)).get(value).toString(),
		// ((ModelData)bs.getModels().get(i)).get(displayvalue)
		// .toString());
		//
		// }
		// }
		//
		bs.setLoader(null);
	}

	public BaseComboBoxForm(BaseStore<D> bs) {

		this("code", "name", bs);
	}

	/**
	 * 
	 * BaseComboBoxForm<BaseModelData> bsb1 = new
	 * BaseComboBoxForm<BaseModelData>("bcode","bname","bcode","",true);//new
	 * BaseComboBoxForm(CodeNameMapFactory.loadBcode_801());
	 * c1.setEditor(bsb1.getCelEditor()); c1.setRenderer(bsb1);
	 * 
	 * 如果是form的方式无需渲染
	 * 
	 * @param value
	 *            储存的字段名
	 * @param displayvalue
	 *            显示的字段名
	 * @param Tablename
	 *            表名
	 * @param filter
	 *            过滤条件 where bcode = ‘222’
	 * @param needrender
	 *            需要渲染，true加入了渲染的hashtable
	 */
	public BaseComboBoxForm(final String value, final String displayvalue,
			String Tablename, String filter, boolean needrender) {
		this();
		ModelType combotype = new ModelType();
		combotype.setRoot("records");
		combotype.setRecordName("record");
		combotype.setTotalName("totle");
		combotype.addField("code");
		combotype.addField("name");

		StoreInfo comboinfo = new StoreInfo();
		comboinfo.setTablename("bcode");
		// comboinfo.setForcenolimit("yes");
		comboinfo.setForcenolimit("true");
		comboinfo.setSql("select " + value + " as code," + displayvalue
				+ " as name from " + Tablename + " " + filter);
		bs = new BaseStore<D>(combotype, comboinfo) {
			/* (non-Javadoc)
			 * @see com.extjs.gxt.ui.client.store.Store#isFiltered(com.extjs.gxt.ui.client.data.ModelData, java.lang.String)
			 * 重写STORE的方法，主要用于查询的方便
			 */
			@Override
			protected boolean isFiltered(ModelData record, String property) {
			    if (filterBeginsWith != null && property != null) {
			      Object o = record.get(property);
			      if (o != null) {
			        if (o.toString().toLowerCase().indexOf(filterBeginsWith.toLowerCase()) == -1) {
			          return true;
			        }
			      }
			    }
			    if (filters != null) {
			      for (StoreFilter filter : filters) {
			        boolean result = filter.select(this, record, record, property);
			        if (!result) {
			          return true;
			        }
			      }
			    }
			    return false;
			  }
		};

		this.value = "code";
		this.displayvalue = "name";
		this.setStore(bs);
		this.setDisplayField("name");
		//setTypeAhead(true);
		setTriggerAction(TriggerAction.ALL);
		setAutoValidate(true);
		if (needrender)
			bs.getLoader().addLoadListener(new LoadListener() {
				public void loaderLoad(LoadEvent le) {
					ht.clear();

					for (int i = 0; i < bs.getModels().size(); i++) {

						if (!(((ModelData) bs.getModels().get(i)).get("code") == null || ((ModelData) bs
								.getModels().get(i)).get("name") == null))
							ht.put(((ModelData) bs.getModels().get(i)).get(
									"code").toString(), ((ModelData) bs
									.getModels().get(i)).get("name").toString());
					}
				}
			});

		bs.setLoader(null);
	}

	public BaseComboBoxForm(final String value, final String displayvalue,
			String sqltablename, boolean needrender,String macro) {
		this();
		
		bs = new BaseStore<D>();

		CommandSyncContainer list = new CommandSyncContainer();

		CommandSyncGetModelDatas csgmd = new CommandSyncGetModelDatas();
		csgmd.setSqlname(sqltablename);
		 csgmd.putmacro("MACRO", macro);
		list.add(csgmd);
		final com.base.myproject.client.tools.GreetingServiceAsync greetingService = GWT
				.create(com.base.myproject.client.tools.GreetingService.class);
		greetingService.SendCommandSync(list,
				new AsyncCallback<CommandSyncReturnObject>() {

					@Override
					public void onFailure(Throwable caught) {
						MessageBox.alert("错误", "网络连接失败", null);

					}

					@Override
					public void onSuccess(CommandSyncReturnObject result) {
						if (result.isB()) {
						
							if (result.getCommandsync() instanceof CommandSyncGetModelDatas) {

								// bcodestore.removeAll();

								bs.add((List<D>)((CommandSyncGetModelDatas) (result
										.getCommandsync())).getList(), false);
								
						
							}

						} else {
							MessageBox.alert("错误", "" + result.getMessage(),
									null);

						}

					}

				});

		this.value = "code";
		this.displayvalue = "name";
		this.setStore(bs);
		this.setDisplayField("name");
		setTypeAhead(true);
		setTriggerAction(TriggerAction.ALL);
		// setAutoValidate(true);
//		if (needrender)
		/*	bs.getLoader().addLoadListener(new LoadListener() {
				public void loaderLoad(LoadEvent le) {
					ht.clear();

					for (int i = 0; i < bs.getModels().size(); i++) {

						if (!(((ModelData) bs.getModels().get(i)).get("code") == null || ((ModelData) bs
								.getModels().get(i)).get("name") == null))
							ht.put(((ModelData) bs.getModels().get(i)).get(
									"code").toString(), ((ModelData) bs
									.getModels().get(i)).get("name").toString());

					}
				}
			});*/

		bs.setLoader(null);
	}

	protected boolean validateValue(String value) {
		doForce();

		for (D c : getStore().getModels()) {
			if (value.equals(c.get("name"))) {
				return true;
			}

		}
		markInvalid("没有对应的值，请重新选择！");
		return false;
	}

	@Override
	protected void triggerBlur(ComponentEvent ce) {

		super.triggerBlur(ce);

	}

	public void setValue(D value) {

		if (value instanceof ModelData) {
			// super.set(((ModelData)value).get("code"));
			super.setValue(value);
		}

		else {
			super.setValue(null);

		}
	}

	/**
	 * 取得codenamemap 的code的值
	 * 
	 * @return
	 */
	public String getValueCode() {
		if (getValue() == null)
			return null;
		return getValue().get(value);
	}

	/**
	 * 取得codenamemap的name值
	 * 
	 * @return
	 */
	public String getValueName() {
		return getDisplayField();
	}

	/**
	 * Sets the combo value.
	 * 
	 * @param value
	 *            the value
	 */
	// zgw 2009-10-31 原来是 value 的类型是D
	public void setSimpleValue(Object value) {

		D c = findModel(value);

		if (c != null) {
			setValue(c);
		} else {
			setValue(null);
		}
	}

	public D findModel(Object value) {
		D val = null;
		store.clearFilters();

		if (value instanceof ModelData) {
			// return ((ModelData) value).get("code");
			return ((D) value);
		}
		for (D c : store.getModels()) {

			if (c.get("code") != null && c.get("code").equals(value)) {
				val = c;
				break;
			}
		}
		return val;
	}

	public D getSimpleValue() {
		D c = getValue();
		if (c != null) {
			return c;
		}

		return null;
	}

	@Override
	public Object render(ModelData model, String property, ColumnData config,
			int rowIndex, int colIndex, ListStore store, Grid grid) {
		// TODO Auto-generated method stub
		if (bs != null) {
			// Debug.printf(bs);
			// Debug.printf(bs.findModel("code", "10101"));
			// Debug.printf(bs.findModel("code", "10101").get("name"));
			// return bs.findModel("code", "10101").get("name");
		}
		//
		if ((model.get(property) instanceof ModelData)) {
			return ((ModelData) model.get(property)).get("name");
		} else {
			ModelData md = this.store.findModel("code", model.get(property));
			if (md != null) {
				return md.get("name");
			} else
				return model.get(property);
		}
		
//		if (ht.containsKey(model.get(property)))
//			return ht.get(model.get(property));
//		else if (model.get(property) instanceof ModelData) {
//			return ((ModelData) model.get(property)).get("name");
//		} else
//			return model.get(property);
	}

	public ModelData findModel(Object value, String key, String b) {
		for (ModelData md : store.getModels()) {
			if (md.get(key).equals(value) || value == md) {
				return md;
			}
		}
		// //否则返回第一行记录
		// if(store.getModels().size()>0)
		// return store.getModels().get(0);
		return null;
	}

	public void setSql(String sql)
	
	{
		if(bs!=null)
		{
		 bs.getStoreinfo().setSql(sql);
		 bs.reload();
		}
	}
	public CellEditor getCelEditor() {
		return new CellEditor(this) {
			public Object preProcessValue(Object value) {

				if (value == null) {
					return value;
				}

				return ((BaseComboBoxForm) this.getField()).findModel(value,
						"code", "");
				// return ;

			}
		};

	}

	public java.util.Map<String, String> getHt() {
		return ht;
	}
}
